import {
	ActionType,
	FooterToolbar,
	PageContainer,
	ProColumns,
	ProDescriptions,
	ProDescriptionsItemProps,
	ProTable,
} from '@ant-design/pro-components';
import { Button, Divider, Drawer, message, Popconfirm } from 'antd';
import React, { useRef, useState } from 'react';
import ModalCard from '../ModalCard';
import { AxiosResponse } from 'axios';
import R from '../../utils/ramda'

// type Test = {
// 	a: string;
// 	c: string
// 	b: number;
// }

// type TestString = {
// 	[K in keyof Test]: Test[K] extends string ? K : never
// }[keyof Test]

// const t: Test = {
// 	a: '',
// 	b: 1
// }


type CRUDProps<T> = {
	columns: ProColumns<T>[];
	creatFormColumns?: ProColumns<T>[];
	updateFormColumns?: ProColumns<T>[];
	rowKey: {
		[K in keyof T]: T[K] extends string ? K : never
	}[keyof T] & string;
	api: {
		queryList: (params: {
			current?: number | undefined;
			pageSize?: number | undefined;
		}, options?: {
			[key: string]: any;
		} | undefined) => Promise<AxiosResponse<any, any>>;
		add: (body?: Partial<T> | undefined, options?: {
			[key: string]: any;
		} | undefined) => Promise<AxiosResponse<any, any>>;
		modify: (body?: Partial<T> | undefined, options?: {
			[key: string]: any;
		} | undefined) => Promise<AxiosResponse<any, any>>;
		removeById: (id: string, options?: {
			[key: string]: any;
		} | undefined) => Promise<AxiosResponse<any, any>>;
		remove: (data: {
			ids: string[];
		}, options?: {
			[key: string]: any;
		} | undefined) => Promise<AxiosResponse<any, any>>;
	}
}


function CRUD<T = any>(props: CRUDProps<T>) {
	const [createModalVisible, handleModalVisible] = useState<boolean>(false);
	const [updateModalVisible, handleUpdateModalVisible] =
		useState<boolean>(false);
	const [stepFormValues, setStepFormValues] = useState<T | {}>({});
	const actionRef = useRef<ActionType>();
	const [row, setRow] = useState<T>();
	const [selectedRowsState, setSelectedRows] = useState<T[]>([]);

	/**
	 * 添加节点
	 * @param fields
	 */
	const handleAdd = async (fields: T) => {
		const hide = message.loading('正在添加');
		try {
			await props.api.add({ ...fields });
			hide();
			message.success('添加成功');
			return true;
		} catch (error) {
			hide();
			message.error('添加失败请重试！');
			return false;
		}
	};

	/**
	 * 更新节点
	 * @param fields
	 */
	const handleUpdate = async (fields: Partial<T>) => {
		const hide = message.loading('正在修改');
		try {
			await props.api.modify(fields);
			hide();
			message.success('修改成功');
			return true;
		} catch (error) {
			hide();
			message.error('修改失败请重试！');
			return false;
		}
	};


	const handleRemove = async (id: string) => {
		const hide = message.loading('正在删除');
		try {
			await props.api.removeById(id);
			hide();
			message.success('删除成功，即将刷新');
			return true;
		} catch (error) {
			hide();
			message.error('删除失败，请重试');
			return false;
		}
	};
	const handleRemoveSelected = async (selectedRows: T[]) => {
		const hide = message.loading('正在删除');
		if (!selectedRows) return true;
		try {
			await props.api.remove({
				ids: selectedRows.map(it => `${it[props.rowKey]}`) || []
			});
			hide();
			message.success('删除成功，即将刷新');
			return true;
		} catch (error) {
			hide();
			message.error('删除失败，请重试');
			return false;
		}
	};

	const option: ProColumns<T> = {
		title: '操作',
		width: 200,
		fixed: 'right',
		dataIndex: 'option',
		valueType: 'option',
		render: (_, record) => (
			<>
				<Button type='primary'
					onClick={() => {
						setStepFormValues((_: any) => ({ ...record }));
						handleUpdateModalVisible(true);
					}}
				>
					修改
				</Button>
				<Divider type="vertical" />
				<Popconfirm
					title="确定要删除吗？"
					onConfirm={async () => {
						const success = await handleRemove(`${record[props.rowKey]}`)
						if (success) {
							actionRef.current?.reloadAndRest?.()
						}
					}}
					okText="确定"
					cancelText="取消"
				>
					<Button type='primary' danger >删除</Button>
				</Popconfirm>
			</>
		),
	}

	const columns = R.append(option, props.columns)
	const createFormColumns = props.creatFormColumns ?? props.columns
	const updateFormColumns = props.updateFormColumns ?? props.columns


	return (
		<PageContainer
			header={{
				title: '地址管理',
			}}
		>
			<ProTable<T>
				headerTitle="查询表格"
				actionRef={actionRef}
				rowKey={props.rowKey}
				search={{
					labelWidth: 120,
				}}
				toolBarRender={() => [
					<Button
						key="1"
						type="primary"
						onClick={() => handleModalVisible(true)}
					>
						新建
					</Button>,
				]}
				request={props.api.queryList}
				columns={columns}
				rowSelection={{
					onChange: (_, selectedRows) => setSelectedRows(selectedRows),
				}}
			/>
			{selectedRowsState?.length > 0 && (
				<FooterToolbar
					extra={
						<div>
							已选择{' '}
							<a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '}
							项&nbsp;&nbsp;
						</div>
					}
				>
					<Popconfirm
						title="确定要删除吗？"
						onConfirm={async () => {
							await handleRemoveSelected(selectedRowsState);
							setSelectedRows([]);
							actionRef.current?.reloadAndRest?.();
						}}
						okText="确定"
						cancelText="取消"
					>
						<Button>批量删除</Button>
					</Popconfirm>
				</FooterToolbar>
			)}
			<ModalCard
				onCancel={() => handleModalVisible(false)}
				modalVisible={createModalVisible}
			>
				<ProTable<T, T>
					onSubmit={async (value) => {
						const success = await handleAdd(value);
						if (success) {
							handleModalVisible(false);
							if (actionRef.current) {
								actionRef.current.reload();
							}
						}
					}}
					rowKey={props.rowKey}
					type="form"
					columns={createFormColumns}
				/>
			</ModalCard>
			{stepFormValues && Object.keys(stepFormValues).length > 0 ?
				<ModalCard
					onCancel={() => {
						handleUpdateModalVisible(false)
						setStepFormValues({})
					}}
					modalVisible={updateModalVisible}
				>
					<ProTable<T, T>
						form={{ initialValues: stepFormValues }}
						onSubmit={async (value) => {
							const success = await handleUpdate(value);
							if (success) {
								handleUpdateModalVisible(false);
								setStepFormValues({})
								if (actionRef.current) {
									actionRef.current.reload();
								}
							}
						}}
						rowKey={props.rowKey}
						type="form"
						columns={updateFormColumns}
					/>
				</ModalCard>
				: null
			}

			<Drawer
				width={600}
				visible={!!row}
				onClose={() => {
					setRow(undefined);
				}}
				closable={false}
			>
				{row?.[props.rowKey] && (
					<ProDescriptions<T>
						column={2}
						title={`${row?.[props.rowKey]}`}
						request={async () => ({
							data: row || {},
						})}
						params={{
							id: row?.[props.rowKey],
						}}
						columns={props.columns as ProDescriptionsItemProps<T>[]}
					/>
				)}
			</Drawer>
		</PageContainer>
	);
}

export default CRUD;